/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


package com.gestionabsences.form;

import com.gestionabsences.beans.MapMatters;
import com.gestionabsences.beans.ResultRequest;
import com.gestionabsences.config.DAOFactory;
import com.gestionabsences.database.ToolsRequest;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
/**
 *
 * @author Krystle
 */
public class FormTeacher {
    
    public static final String CHAMP_MATIERE = "matiere";
    public static final String CHAMP_OPTION_NBRE_ABSENCES = "optionNbrAbsences";
    public static final String CHAMP_NBRE_ABSENCES = "nbrAbsences";
    public static final String CHAMP_OPTION = "option";
    public static final String CHAMP_ERREUR = "erreur";
    
    private Map<String, String> erreurs;
    private MapMatters listeMatieres;
    private DAOFactory dao;
    private String immatriculation;
    
    private String formerValMatiere;
    private String formerValNbreAbsences;
    private String formerValOptionNbreAbsences;
    private String formerValOption;
    
    public FormTeacher(DAOFactory dao, MapMatters listMatieres, String immatriculation) {
	this.erreurs = new HashMap<String, String>();
	this.listeMatieres = listMatieres;
	this.dao = dao;
	this.immatriculation = immatriculation;
    }
    
    public ResultRequest creationResultat( HttpServletRequest request ) {
	
	String id_matiere = getValeurChamp( request, CHAMP_MATIERE );
	String optionNbrAbsences = getValeurChamp( request, CHAMP_OPTION_NBRE_ABSENCES);
	String option = getValeurChamp( request, CHAMP_OPTION );
	String nbrAbsences = getValeurChamp( request, CHAMP_NBRE_ABSENCES );

	double nbr_absences = -1;
	
	try {
            validationOptionNbreAbsences( optionNbrAbsences );
	    
	    try {
		nbr_absences = validationNbreAbsences(nbrAbsences, optionNbrAbsences);
	    } catch (Exception e) {
		setErreur( CHAMP_NBRE_ABSENCES, e.getMessage() );
	    }
        } catch ( Exception e ) {
            setErreur( CHAMP_OPTION_NBRE_ABSENCES, e.getMessage() );
        }
	
	try {
            validationMatiere( id_matiere );
        } catch ( Exception e ) {
            setErreur( CHAMP_MATIERE, e.getMessage() );
        }
	
	try {
            validationOption( option );
        } catch ( Exception e ) {
            setErreur( CHAMP_OPTION, e.getMessage() );
        }
	
	ResultRequest res = null;
	
	if( erreurs.isEmpty() ) {
	    formerValMatiere = id_matiere;
	    formerValOption = option;
	    formerValNbreAbsences = nbrAbsences;
	    formerValOptionNbreAbsences = optionNbrAbsences;
	    
	    res = createResultFromArgs(id_matiere, optionNbrAbsences, nbr_absences, option);
	    if(res != null) {
		if( !res.isResultatPresent() ) {
		res = null;
		}
	    }
	}
	
	return res;
    }
    
    private double validationNbreAbsences(String nbrAbsences, String optionNbreAbsences) throws Exception {
	double temp;
	
	if(optionNbreAbsences.compareTo("NEVER") == 0 || optionNbreAbsences.compareTo("ALWAYS") == 0 || optionNbreAbsences.compareTo("WITHOUT") == 0) {
	    return -2;
	}
	
	if (nbrAbsences != null) {
	    try {
		temp = Double.parseDouble(nbrAbsences);
		if (temp < 0) {
		    throw new Exception("Le nombre d'absence doit être un nombre positif.");
		}
	    } catch (NumberFormatException e) {
		temp = -1;
		throw new Exception("Le nombre d'absence doit être un nombre.");
	    }
	} else {
	    temp = -1;
	    throw new Exception("Merci d'entrer un nombre d'absence.");
	}
	
	return temp;
    }
    
    private void validationOptionNbreAbsences(String optionNbreSeance) throws Exception {
	final String OPTION1 = ">=";
	final String OPTION2 = ">";
	final String OPTION3 = "<";
	final String OPTION4 = "=";
	final String OPTION5 = "<=";
	final String OPTION6 = "ALWAYS";
	final String OPTION7 = "NEVER";
	final String OPTION8 = "WITHOUT";
	
	if( optionNbreSeance.compareTo(OPTION1) != 0 && optionNbreSeance.compareTo(OPTION2) != 0 && optionNbreSeance.compareTo(OPTION3) != 0
		&& optionNbreSeance.compareTo(OPTION4) != 0 && optionNbreSeance.compareTo(OPTION5) != 0 && optionNbreSeance.compareTo(OPTION6) != 0
		&& optionNbreSeance.compareTo(OPTION7) != 0 && optionNbreSeance.compareTo(OPTION8) != 0 ) {
	    throw new Exception( "L'opérateur '" + optionNbreSeance + "' n'est pas valable." );
	}
    }
    
    private void validationOption(String option) throws Exception {
	final String OPTION1 = "ALL";
	final String OPTION2 = "withJustifications";
	final String OPTION3 = "withoutJustifications";
	
	if (option != null) {
	    if (option.compareTo(OPTION1) != 0 && option.compareTo(OPTION2) != 0 && option.compareTo(OPTION3) != 0) {
		throw new Exception("L'option '" + option + "' n'est pas valable.");
	    }
	} else {
	    throw new Exception("Une option doit être spécifiée.");
	}
    }
    
    private void validationMatiere( String idMatiere ) throws Exception {
	if (idMatiere.compareTo("IN_ONE") != 0 && idMatiere.compareTo("ALL") != 0) {
	    if (idMatiere != null) {
		if (!this.listeMatieres.containsKey(idMatiere)) {
		    throw new Exception("Le nom de matière spécifié n'existe pas.");
		}
	    } else {
		throw new Exception("Une matière doit être spécifiée pour faire la recherche.");
	    }
	}
    }
    
    private ResultRequest createResultFromArgs(String id_matiere, String optionNbrAbsences, double nbrAbsences, String option) {
	
	ArrayList<String> tabColonnes = new ArrayList<String>();
	tabColonnes.add("ine");
	tabColonnes.add("nom");
	tabColonnes.add("prenom");
	tabColonnes.add("affectation");
	
	// traitement pour la justification
	int attrJustification;
	if(option.compareTo("withoutJustifications") == 0) {
	    attrJustification = 0;
	} else if(option.compareTo("withJustifications") == 0) {
	    attrJustification = 1;
	} else {
	    attrJustification = 2;
	}
	
	String sql_req;
	
	if( optionNbrAbsences.compareTo("ALWAYS") == 0 ) {
	    if (id_matiere.compareTo("ALL") == 0) {
		sql_req = "SELECT * FROM getAlwaysAbsentInAll('" + this.immatriculation + "', " + attrJustification + ");";
	    } else {
		sql_req = "SELECT * FROM getAlwaysAbsentForEverything(" + id_matiere + ", " + attrJustification + ");";
	    }
	} else if( optionNbrAbsences.compareTo("NEVER") == 0 ){
	    if (id_matiere.compareTo("ALL") == 0) {
		sql_req = "SELECT * FROM getNeverAbsentForAll('"+ this.immatriculation +"');";
	    } else {
		sql_req = "SELECT * FROM getNeverAbsentIn(" + id_matiere + ");";
	    }
	} else {
	    tabColonnes.add("nb_absences");
	    
	    String fonctionSQL = (id_matiere.compareTo("ALL") == 0) ? "getOPERATORXAbsenceInAll('" + this.immatriculation + "'" : (id_matiere.compareTo("IN_ONE") == 0) ? "getOPERATORXAbsenceByCourse('" + this.immatriculation + "'" : "getOPERATORXAbsenceIn(" + id_matiere;
	    if(id_matiere.compareTo("IN_ONE") == 0) {
		tabColonnes.add("matiere");
	    }
	    
	    
	    String condition = " WHERE Q.nb_absences ";
	    String op;
	    boolean pCondition = true;
	    if( optionNbrAbsences.compareTo(">=") == 0 )
	    {
		op = ">=";
	    } else if( optionNbrAbsences.compareTo("<=") == 0 ) {
		op = "<=";
	    } else if( optionNbrAbsences.compareTo("<") == 0 ) {
		op = "<";
	    } else if( optionNbrAbsences.compareTo(">") == 0 ) {
		op = ">";
	    } else if( optionNbrAbsences.compareTo("=") == 0 ) {
		op = "=";
	    } else { // WITHOUT condition
		op= "";
		pCondition = false;
	    }
	    
	    sql_req = "SELECT Q.* FROM " + fonctionSQL + ", " + attrJustification + ") Q" + ((pCondition) ? condition + op + " " + (int) nbrAbsences : "") + ";";
	}
	
	Connection connexion = null;
	ResultRequest res = null;
	
	try {
	    connexion = dao.getConnection();
	    
	    PreparedStatement preparedStatement = null;
	    ResultSet resultSet = null;
	
	    try {
		preparedStatement = ToolsRequest.prepareRequest( connexion, sql_req, false);
		//setErreur( CHAMP_ERREUR, preparedStatement.toString() );
		System.out.println("query :  " + preparedStatement.toString());
		
		resultSet = preparedStatement.executeQuery();
		
		res = new ResultRequest(resultSet, tabColonnes.toArray());
				
	    } catch(Exception e) {
		setErreur( CHAMP_ERREUR, preparedStatement.toString() + " => " + e.getMessage() );
	    }
	    finally {
		ToolsRequest.close(preparedStatement, resultSet);
	    }
	} catch (SQLException e) {
	    setErreur( CHAMP_ERREUR, e.getMessage() );
	}
	finally {
	    ToolsRequest.close(connexion);
	}
	
	return res;
    }
    
    public String getFormerValMatiere() {
	return this.formerValMatiere;
    }
    
    public String getFormerValOption() {
	return this.formerValOption;
    }
    
    public String getFormerValNbreAbsences() {
	return this.formerValNbreAbsences;
    }
    
    public String getFormerValOptionNbreAbsences() {
	return this.formerValOptionNbreAbsences;
    }
        
    public Map<String, String> getErreurs() {
        return erreurs;
    }
    
    private void setErreur( String champ, String message ) {
	String previous = erreurs.get(champ);
	if(previous != null) {
	    erreurs.put( champ, previous + message );
	}
	else {
	    erreurs.put( champ, message );
	}
	
    }
    
    private static String getValeurChamp( HttpServletRequest request, String nomChamp ) {
        String valeur = request.getParameter( nomChamp );
        if ( valeur == null || valeur.trim().length() == 0 ) {
            return null;
        } else {
            return valeur;
        }
    }
}
    


